package com.ckv.qcm.view.Utils;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JPanel;


public abstract class ElementPanel extends JPanel
{	
	private enum TypeEvent
	{
		Selected,
		Entered,
		Created
	}
	
	public enum Mode
	{
		CREATE,
		EDIT,
		READ
	}
	
	private final Color defaultBackgroundColor = Color.white;
	private final Color selectedBackgroundColor = new Color(122, 153, 224);
	private final Color enteredBackgroundColor = Color.lightGray;
	
	private int width = 200;
	private int height = 50;
	
	private boolean selected = false;
	private boolean entered = false;
	
	private boolean useEnteredChangeColor = true;
	private boolean useSelectedChangeColor = true;
	
	protected Mode mode = Mode.READ;
	
	protected ArrayList<ElementPanelHandler> handlers = new ArrayList<ElementPanelHandler>();
	
	public ElementPanel()
	{
		super();
		init();
	}
	
	public ElementPanel(int width,int height)
	{
		super();
		this.width = width;
		this.height = height;
		init();
	}
	
	public int getWidth() 
	{
		return width;
	}

	public Mode getMode()
	{
		return this.mode;
	}
	
	public void setWidth(int width)
	{
		this.width = width;
		resize();
	}

	public int getHeight() 
	{
		return height;
	}

	public void setHeight(int height)
	{
		this.height = height;
		resize();
	}

	public Color getDefaultBackgroundColor()
	{
		return defaultBackgroundColor;
	}

	public Color getSelectedBackgroundColor()
	{
		return selectedBackgroundColor;
	}

	public Color getEnteredBackgroundColor() 
	{
		return enteredBackgroundColor;
	}
	
	public boolean isUseEnteredChangeColor() 
	{
		return useEnteredChangeColor;
	}

	public void setUseEnteredChangeColor(boolean useEnteredChangeColor)
	{
		this.useEnteredChangeColor = useEnteredChangeColor;
	}

	public boolean isUseSelectedChangeColor() {
		return useSelectedChangeColor;
	}

	public void setUseSelectedChangeColor(boolean useSelectedChangeColor) {
		this.useSelectedChangeColor = useSelectedChangeColor;
	}

	public boolean isSelected()
	{
		return selected;
	}

	public void addHandler(ElementPanelHandler handler)
	{
		this.handlers.add(handler);
	}
	
	public void removeHandler(ElementPanelHandler handler)
	{
		this.handlers.remove(handler);
	}
	
	private void resize()
	{
		this.setPreferredSize(new Dimension(this.width,this.height));
		this.validate();
	}
	
	private void init()
	{	
		this.setPreferredSize(new Dimension(width,height));
		this.setBackground(defaultBackgroundColor);
		
		
		this.addMouseListener(new MouseListener() 
		{
			
			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseExited(MouseEvent e) 
			{
				if(entered)
					leave();
			}
			
			@Override
			public void mouseEntered(MouseEvent e) 
			{
				if(!entered)
					enter();
				
			}
			
			@Override
			public void mouseClicked(MouseEvent e) 
			{
				if(selected)
					unselect();
				else
					select();
			}
		});
		
	}
	
	public void select()
	{
		if(useSelectedChangeColor)
		{
			this.setBackground(selectedBackgroundColor);
		}
		raiseEvent(TypeEvent.Selected);
		this.selected = true;
	}
	
	public void enter()
	{
		if(!selected)
		{
			this.entered = true;
			
			if(useEnteredChangeColor)
				this.setBackground(enteredBackgroundColor);
		}
	}
	
	public void unselect()
	{
		this.selected = false;
		this.entered = false;
		this.setBackground(defaultBackgroundColor);
	}
	
	public void leave()
	{
		if(!selected)
		{
			this.entered = false;
			this.setBackground(defaultBackgroundColor);
		}
	}

	public abstract void focus();
	
	private void raiseEvent(TypeEvent evt)
	{
		for (ElementPanelHandler handler : handlers)
		{
			switch (evt)
			{
			case Selected:
				handler.onSelected(this);
				break;

			default:
				break;
			}
		}
	}
	
	public abstract  void switchMode(Mode mode);
}
